﻿using Application.HandleEvents.RestartEvents;
using FrameworkCore.Constants;
using FrameworkCore.Controllers;
using FrameworkCore.Events;
using FrameworkCore.Extensions;
using FrameworkCore.Helpers;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace AiBLSmartEdu.Module.Manager.API;

/// <summary>
/// 模块管理
/// </summary>
public partial class ManagerController : BaseModuleController
{
    private readonly ILogger<ManagerController> _logger;
    private readonly IHttpContextAccessor _httpContextAccessor;
    private readonly IEventPublisher _eventPublisher;

    public ManagerController(
        ILogger<ManagerController> logger,
        IHttpContextAccessor httpContextAccessor,
        IEventPublisher eventPublisher)
    {
        _logger = logger;
        _httpContextAccessor = httpContextAccessor;
        _eventPublisher = eventPublisher;
    }

    /// <summary>
    /// 安装模块
    /// </summary>
    /// <param name="files">要上传的文件集合</param>
    /// <returns></returns>
    [HttpPost("Install")]
    public async Task<IActionResult> Install(List<IFormFile> files)
    {
        // 检查文件集合是否为空
        if (files == null || files.Count == 0)
        {
            return Ok("没有选择要上传的文件");
        }

        // 获取包安装目录
        string packagesDirectory = ApplicationPartManagerExtensions.GetPackagesDirectory();

        List<string> successMessages = new List<string>();
        List<string> errorMessages = new List<string>();

        foreach (var file in files)
        {
            if (file.Length == 0)
            {
                errorMessages.Add($"文件 '{file.FileName}' 为空");
                continue;
            }

            string fullPath = Path.Combine(packagesDirectory, file.FileName);

            string fileExtension = Path.GetExtension(fullPath);
            if (fileExtension != GlobalConstants.NugetPackageSuffix)
            {
                errorMessages.Add($"文件 '{file.FileName}' 格式不正确");
                continue;
            }

            try
            {
                // 创建目录（如果不存在）
                Directory.CreateDirectory(packagesDirectory);

                // 将文件保存到磁盘，存在则覆盖
                using (var stream = new FileStream(fullPath, FileMode.Create))
                {
                    await file.CopyToAsync(stream);
                }

                successMessages.Add($"文件 '{file.FileName}' 上传成功");
            }
            catch (Exception ex)
            {
                errorMessages.Add($"文件 '{file.FileName}' 上传失败: {ex.Message}");
            }
        }

        if (errorMessages.Count > 0)
        {
            return StatusCode(500, string.Join("\n", errorMessages));
        }

        return Ok(string.Join("\n", successMessages));
    }

    /// <summary>
    /// 卸载模块
    /// </summary>
    /// <param name="moduleName"></param>
    /// <returns></returns>
    [HttpPost("Unload")]
    public async Task<IActionResult> Unload(string moduleName)
    {
        if (string.IsNullOrEmpty(moduleName))
        {
            return StatusCode(404, $"{moduleName}模块不存在");
        }

        var fileName = $"{moduleName.Replace(GlobalConstants.NugetPackageSuffix, "")}{GlobalConstants.NugetPackageSuffix}";

        string packages = Path.Combine(ApplicationPartManagerExtensions.GetPackagesDirectory(), fileName);

        // 如果文件存在，删除它
        if (System.IO.File.Exists(packages))
        {
            System.IO.File.Delete(packages);
        }
        else
        {
            return StatusCode(404, $"{moduleName}模块不存在");
        }

        return await Task.FromResult(Ok("模块正在卸载......"));
    }

    /// <summary>
    /// 重启应用程序
    /// </summary>
    /// <returns></returns>
    [HttpPost("Restart")]
    public async Task<IActionResult> Restart()
    {
        var stopApplicationEvent = new StopApplicationEvent();
        await _eventPublisher.PublishAsync(new Event<StopApplicationEvent>(stopApplicationEvent));

        string exePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, GlobalConstants.HostRestartManager);
        string args1 = AppDomain.CurrentDomain.FriendlyName;
        string args2 = ApplicationPartManagerExtensions.GetPackagesDirectory();
        string args3 = AppDomain.CurrentDomain.BaseDirectory;

        string arguments = $"{args1} {args2} {args3}";

        CmdHelper.ExecuteExternalProcess(exePath, arguments);

        return await Task.FromResult(Ok("重启应用程序......"));
    }
}
